from django import forms


from web import models
from django.core.exceptions import ValidationError
import random
from django.core.validators import RegexValidator
from utils.tencent.sms import send_sms_single
from django.conf import settings
from django_redis import get_redis_connection
from utils import encrpt
from web.forms.bootstrap import BootstrapForm

class RegisterModelForm(BootstrapForm,forms.ModelForm):
    mobile_phone = forms.CharField(label='手机号',validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$','手机号格式错误'),])
    password = forms.CharField(
        label='密码',
        min_length=8,
        max_length=64,
        error_messages={
            'min_length': "密码长度不能小于8个字符",
            'max_length': "密码长度不能大于64个字符",
        },
        widget=forms.PasswordInput()
    )
    confirm_password = forms.CharField(
        label='重复密码',
        min_length=8,
        max_length=64,
        error_messages={
            'min_length': "重复密码长度不能小于8个字符",
            'max_length': "重复密码长度不能大于64个字符",
        },
        widget=forms.PasswordInput()
    )
    code = forms.CharField(label='验证码',widget=forms.TextInput())
    class Meta:
        model = models.UserInfo
        fields = ['username','email','password','confirm_password','mobile_phone','code']

    def clean_username(self):
        username = self.cleaned_data['username']
        exists = models.UserInfo.objects.filter(username=username).exists()
        if exists:
            raise ValidationError('用户名已存在')
        return username

    def clean_email(self):
        email = self.cleaned_data['email']
        exists = models.UserInfo.objects.filter(email=email).exists()
        if exists:
            raise ValidationError('用户名已存在')
        return email

    def clean_password(self):
        pwd = self.cleaned_data['password']
        #加密&返回
        return encrpt.md5(pwd)

    def clean_confirm_password(self):
        pwd = self.cleaned_data.get('password')
        confirm_pwd = encrpt.md5(self.cleaned_data['confirm_password'])
        if pwd != confirm_pwd:
            raise ValidationError('两次密码不一致')
        return confirm_pwd

    def clean_mobile_phone(self):
        mobile_phone = self.cleaned_data['mobile_phone']
        print(f"[DEBUG] 存储手机号原始值：'{mobile_phone}'")  # 检查是否有空格或特殊字符
        exists = models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
        if exists:
            raise ValidationError('手机号已经注册')
        return mobile_phone

    def clean_code(self):
        code = self.cleaned_data['code']
        mobile_phone = self.cleaned_data.get('mobile_phone')
        print(f"[DEBUG] 读取手机号原始值：'{mobile_phone}'")  # 检查是否一致
        conn = get_redis_connection()
        redis_code = conn.get(f"sms_code:{mobile_phone}")  # 必须与存储时的键名一致

        print(f"[DEBUG] 读取验证码：手机号={mobile_phone}, Redis中的验证码={redis_code}")  # 调试输出
        if not redis_code:
            raise ValidationError('验证码失效或未发送,请重新发送')
        redis_str_code = redis_code.decode('utf-8')
        if code.strip() != redis_str_code:
            raise ValidationError('验证码错误,请重新输入')
        return code





class SendSmsForm(forms.Form):
    mobile_phone = forms.CharField(label='手机号',validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$','手机号格式错误'),])

    def __init__(self,request,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.request = request



    def clean_mobile_phone(self):
        mobile_phone = self.cleaned_data['mobile_phone']
        # tpl = self.request.GET.get('tpl')
        # template_id = settings.TENCENT_SMS_TEMPLATE.get(tpl)
        # if not template_id:
        #     raise ValidationError('短信模板错误')
        exists = models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
        # if exists:
        #     raise ValidationError('手机号已存在')
        # code = random.randrange(1000,9999)
        # sms = send_sms_single(mobile_phone,template_id,[code,])
        # if sms['result'] != 0:
        #     raise ValidationError('短信发送失败，{}'.format(sms['errmsg']))

        code ="1234"

        try:
            conn = get_redis_connection()
            conn.set(f"sms_code:{mobile_phone}", code, ex=300)  # 添加前缀避免键冲突
            print(f"[DEBUG] 存储验证码成功：手机号={mobile_phone}, 验证码={code}")
        except Exception as e:
            print(f"[ERROR] Redis 存储失败：{str(e)}")
            raise ValidationError('系统错误，请稍后重试')

        return mobile_phone


class loginSMSForm(BootstrapForm,forms.Form):
    mobile_phone = forms.CharField(label='手机号',validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机号格式错误'), ])
    code = forms.CharField(label='验证码', widget=forms.TextInput())
    def clean_mobile_phone(self):
        mobile_phone = self.cleaned_data['mobile_phone']
        exists = models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
        if not exists:
            raise ValidationError('手机号不存在')
        return mobile_phone

    def clean_code(self):
        code = self.cleaned_data['code']
        mobile_phone = self.cleaned_data.get('mobile_phone')
        if not mobile_phone:
            return code

        conn = get_redis_connection()
        redis_code = conn.get(f"sms_code:{mobile_phone}")  # 必须与存储时的键名一致

        print(f"[DEBUG] 读取验证码：手机号={mobile_phone}, Redis中的验证码={redis_code}")  # 调试输出
        if not redis_code:
            raise ValidationError('验证码失效或未发送,请重新发送')
        redis_str_code = redis_code.decode('utf-8')
        if code.strip() != redis_str_code:
            raise ValidationError('验证码错误,请重新输入')
        return code



class loginForm(BootstrapForm,forms.Form):
    username = forms.CharField(label='邮箱或手机号')
    password = forms.CharField(label='密码',widget=forms.PasswordInput(render_value=True))
    code = forms.CharField(label='图片验证码')

    def __init__(self,request,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.request = request

    def clean_password(self):
        pwd = self.cleaned_data['password']
        return encrpt.md5(pwd)



    def clean_code(self):
        code = self.cleaned_data['code']
        session_code = self.request.session.get('image_code')
        if not session_code:
            raise ValidationError('验证码已过期，请重新获取')

        if code.strip().upper() != session_code.strip().upper():
            raise ValidationError('验证码输入错误')
        return code